#ifndef wxChartCtrl_H
#define wxChartCtrl_H

#include <wx/scrolwin.h>

enum wxChartCtrlStyle
{
	wxSHOW_X_LABEL = 0x0001,
	wxSHOW_Y_LABEL = 0x0002,	
	wxSHOW_X_UNITS = 0x0004,
	wxSHOW_Y_UNITS = 0x0008,
};

#define LABEL_FONT_HEIGHT	20
#define AREA_BORDER			12
#define PRESCALER_CONST		100
#define DEF_VERTS_COUNT		1000
#define DEF_UPDATE_TIME		2000 //1s

typedef struct wxVertex2D
{
public:
	wxVertex2D(double xx = 0, double yy = 0) : x(xx),y(yy) {}	
	double x,y;
}wxVertex2D;

WX_DECLARE_LIST(wxVertex2D, wxCurveData);

typedef struct wxCurveItem
{
public:
	wxCurveItem() {CurvePen = *wxRED_PEN;}

	wxCurveData CurveList;
	wxPen CurvePen;
	size_t UpdItems;
}wxCurveItem;

WX_DECLARE_LIST(wxCurveItem, wxCurvesList);

class wxChartCtrl : public wxScrolledWindow
{
public:
	wxChartCtrl(wxWindow *parent, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize);
	~wxChartCtrl(void);

	size_t AppendNewCurve(size_t maxVerts = DEF_VERTS_COUNT);
	size_t AppendCurve(wxCurveItem *data, size_t maxVerts = DEF_VERTS_COUNT);	
	wxCurveItem* GetCurve(size_t index);
	void AddendCurveData(size_t index, wxVertex2D &v);
	void RemoveCurve(size_t index);	
	void Clear();

	void ScrollCurveEnd_X(size_t index);
	void UpdateChart(unsigned long updateTime = DEF_UPDATE_TIME);
	void ScrollChart(size_t index,unsigned long updateTime = DEF_UPDATE_TIME);
	void SetCurvePen(size_t index,const wxPen &pen);

	void SetXLabel(wxString label);
	void SetYLabel(wxString label);
	void SetChartStyle(long style);	

	void ShowUnits(bool units = true);
	void ShowLabels(bool units = true);

	void SetUnits(double xx, double yy);
	void SetChartXYUnits(double xx, double yy);
	void SetOffset(double xx, double yy);

protected:
	virtual void OnDraw(wxDC &event);
	void OnSize(wxSizeEvent& event);
	void DrawArea(wxDC& dc, wxPoint &pos, wxSize &size);
	void DrawAreaGrid(wxDC& dc, wxPoint &pos, wxSize &size, wxVertex2D &prescal, wxVertex2D &offset, wxVertex2D &unit);
	void DrawLabels(wxDC& dc);
	void DrawUnits(wxDC& dc, wxPoint &pos, wxVertex2D &vert, bool horizontal = true);
	void UpdateCurveDraw(size_t index, size_t count = (size_t)-1);
	void CalcCoords();
	wxPoint GetPresc(wxVertex2D &vertex);
	wxPoint GetPrescPoint(wxVertex2D &vertex);
	wxPoint GetPrescPointInv(wxVertex2D &vertex);
	wxPoint GetPrescPointInvOff(wxVertex2D vertex);
	wxVertex2D GetRealAreaSize();
	wxVertex2D GetRealFromPoint(wxPoint point);
	void FreeVertsIfNeeded(size_t index);

private:
	unsigned short m_Style;
	wxPoint m_AreaStart;
	wxSize m_AreaSize;

	wxVertex2D m_Prescale;	
	wxVertex2D m_Offset;	
	wxVertex2D m_Unit;
	wxCurvesList m_Curves;

	wxString m_XLabel;
	wxString m_YLabel;

	size_t m_MaxVerts;

	unsigned long m_LastUpdateTime;
	bool m_Refresh;
	

	DECLARE_EVENT_TABLE();
};

#endif//wxChartCtrl_H

